package cn.fancy.sdk.floatwindow.fancy;

import android.animation.ObjectAnimator;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.animation.DecelerateInterpolator;
import android.widget.LinearLayout;

/**
 * Created by zhaojh on date 2020/7/6
 */
public class DragLinearImageView extends LinearLayout {
    private float lastX, lastY;
    private boolean isClickDrag = false;
    private DragImageClickListener dragImageListener;
    private CheckClick checkClick = new CheckClick();
    
    
    public DragLinearImageView(Context context) {
        this(context, null);
    }
    
    public DragLinearImageView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }
    
    public DragLinearImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
    
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getActionMasked()) {
            case MotionEvent.ACTION_DOWN:
                
                lastX = event.getRawX();
                lastY = event.getRawY();
                
                isClickDrag = true;
                
                // 超过这个时间未ACTION_UP，不视为点击事件
                postDelayed(checkClick, ViewConfiguration.getTapTimeout());
                
                return true;
            case MotionEvent.ACTION_MOVE:
                //  不要直接用getX和getY,这两个获取的数据已经是经过处理的,容易出现图片抖动的情况
                float distanceX = lastX - event.getRawX();
                float distanceY = lastY - event.getRawY();
                
                if (Math.sqrt(Math.abs(distanceX * distanceX) + Math.abs(distanceY * distanceY)) > 10) {
                    isClickDrag = false;
                }
                
                float nextY = this.getY() - distanceY;
                float nextX = this.getX() - distanceX;
                
                // 不能移出屏幕
                if (nextY < 0) {
                    nextY = 0;
                } else if (nextY > getParentHeight() - this.getHeight()) {
                    nextY = getParentHeight() - this.getHeight();
                }
                if (nextX < 0) {
                    nextX = 0;
                } else if (nextX > getParentWidth() - this.getWidth()) {
                    nextX = getParentWidth() - this.getWidth();
                }
                
                setX(nextX);
                setY(nextY);
                
                lastX = event.getRawX();
                lastY = event.getRawY();
                
                break;
            case MotionEvent.ACTION_UP:
                if (isClickDrag) {
                    if (null != dragImageListener) {
                        // 点击事件
                        dragImageListener.onClick();
                        // 移除延迟事件
                        removeCallbacks(checkClick);
                    }
                }
                isClickDrag = false;
                
                // 贴边
                float toScreenBoundX;
                if (getX() > getParentWidth() / 2) {
                    toScreenBoundX = getParentWidth() - this.getWidth();
                } else {
                    toScreenBoundX = 0;
                }
                
                // 属性动画移动
                ObjectAnimator x = ObjectAnimator.ofFloat(this, "x", this.getX(), toScreenBoundX);
                x.setInterpolator(new DecelerateInterpolator());
                x.setDuration(100);
                x.start();
                break;
        }
        return false;
    }
    
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (null != getParent()) {
            // 避免父View拦截事件
            getParent().requestDisallowInterceptTouchEvent(true);
        }
        return super.onInterceptTouchEvent(ev);
    }
    
    private int getParentWidth() {
        if (null != getParent()) {
            return ((View) getParent()).getWidth();
        } else {
            return 0;
        }
    }
    
    private int getParentHeight() {
        if (null != getParent()) {
            return ((View) getParent()).getHeight();
        } else {
            return 0;
        }
    }
    
    private class CheckClick implements Runnable {
        @Override
        public void run() {
            isClickDrag = false;
        }
    }
    
    public DragImageClickListener getDragImageListener() {
        return dragImageListener;
    }
    
    public void setDragImageListener(DragImageClickListener dragImageListener) {
        this.dragImageListener = dragImageListener;
    }
    
    public interface DragImageClickListener {
        public abstract void onClick();
    }
}
